// This is the main DLL file.

#include "stdafx.h"

#include "WrapperCrane.h"

WrapperDll::WrapperCompParamdef::WrapperCompParamdef( CompParamdef comp )
    :	typeXBeta(comp.typeXBeta),
    kb(comp.kb),
    typeYAlpha(comp.typeYAlpha),
    ka(comp.ka),
    typeR(comp.typeR)
{
    numXBeta = gcnew array<float>(3);
    denXBeta = gcnew array<float>(3);
    pidXBeta = gcnew array<float>(3);
    numYAlpha = gcnew array<float>(3);
    denYAlpha = gcnew array<float>(3);
    pidYAlpha = gcnew array<float>(3);
    numR = gcnew array<float>(3);
    denR = gcnew array<float>(3);
    pidR = gcnew array<float>(3);

    for(int i=0;i<3;i++)
    {
        numXBeta[i] = comp.numXBeta[i];
        denXBeta[i] = comp.denXBeta[i];
        pidXBeta[i] = comp.pidXBeta[i];
        numYAlpha[i] = comp.numYAlpha[i];
        denYAlpha[i] = comp.denYAlpha[i];
        pidYAlpha[i] = comp.pidYAlpha[i];
        numR[i] = comp.numR[i];
        denR[i] = comp.denR[i];
        pidR[i] = comp.pidR[i];
    }
}

WrapperDll::WrapperCompParamdef WrapperDll::WrapperCrane::CompParamdefToWrapperCompParamdef( CompParamdef comp )
{
    WrapperCompParamdef toReturnComp;
    comp = m_crane->GetComp();

    toReturnComp.typeXBeta = comp.typeXBeta;
    toReturnComp.kb = comp.kb;
    toReturnComp.typeYAlpha = comp.typeYAlpha;
    toReturnComp.ka = comp.ka;
    toReturnComp.typeR = comp.typeR;

    toReturnComp.numXBeta = gcnew array<float>(3);
    toReturnComp.denXBeta = gcnew array<float>(3);
    toReturnComp.pidXBeta = gcnew array<float>(3);
    toReturnComp.numYAlpha = gcnew array<float>(3);
    toReturnComp.denYAlpha = gcnew array<float>(3);
    toReturnComp.pidYAlpha = gcnew array<float>(3);
    toReturnComp.numR = gcnew array<float>(3);
    toReturnComp.denR = gcnew array<float>(3);
    toReturnComp.pidR = gcnew array<float>(3);

    for(int i=0;i<3;i++)
    {
        toReturnComp.numXBeta[i] = comp.numXBeta[i];
        toReturnComp.denXBeta[i] = comp.denXBeta[i];
        toReturnComp.pidXBeta[i] = comp.pidXBeta[i];
        toReturnComp.numYAlpha[i] = comp.numYAlpha[i];
        toReturnComp.denYAlpha[i] = comp.denYAlpha[i];
        toReturnComp.pidYAlpha[i] = comp.pidYAlpha[i];
        toReturnComp.numR[i] = comp.numR[i];
        toReturnComp.denR[i] = comp.denR[i];
        toReturnComp.pidR[i] = comp.pidR[i];
    }

    return toReturnComp;
}

CompParamdef WrapperDll::WrapperCrane::WrapperCompParamdefToCompParamdef( WrapperCompParamdef wcomp )
{
    CompParamdef toReturnComp;

    toReturnComp.typeXBeta = wcomp.typeXBeta;
    toReturnComp.kb = wcomp.kb;
    toReturnComp.typeYAlpha = wcomp.typeYAlpha;
    toReturnComp.ka = wcomp.ka;
    toReturnComp.typeR = wcomp.typeR;

    for(int i=0;i<3;i++)
    {
        toReturnComp.numXBeta[i] = wcomp.numXBeta[i];
        toReturnComp.denXBeta[i] = wcomp.denXBeta[i];
        toReturnComp.pidXBeta[i] = wcomp.pidXBeta[i];
        toReturnComp.numYAlpha[i] = wcomp.numYAlpha[i];
        toReturnComp.denYAlpha[i] = wcomp.denYAlpha[i];
        toReturnComp.pidYAlpha[i] = wcomp.pidYAlpha[i];
        toReturnComp.numR[i] = wcomp.numR[i];
        toReturnComp.denR[i] = wcomp.denR[i];
        toReturnComp.pidR[i] = wcomp.pidR[i];
    }

    return toReturnComp;
}

WrapperDll::WrapperCrane::WrapperCrane()
{
    this->m_crane = new Crane();
}

WrapperDll::WrapperCrane::~WrapperCrane()
{
    delete this->m_crane;
    this->m_crane = nullptr;
}

int WrapperDll::WrapperCrane::Run( int ctl_mode,int traj_flag )
{
    return this->m_crane->Run(ctl_mode, traj_flag);
}

int WrapperDll::WrapperCrane::Stop( void )
{
    return this->m_crane->Stop();
}

void WrapperDll::WrapperCrane::Reset( void )
{
    this->m_crane->Reset();
}

int WrapperDll::WrapperCrane::GetCommand( void )
{
    return this->m_crane->GetCommand();
}

void WrapperDll::WrapperCrane::Wait( int command )
{
    this->m_crane->Wait(command);
}

int WrapperDll::WrapperCrane::GetErr( void )
{
    return this->m_crane->GetErr();
}

void WrapperDll::WrapperCrane::ClearErr( void )
{
    this->m_crane->ClearErr();
}

int WrapperDll::WrapperCrane::LoadTrajFile( System::String^ path )
{
    char* ppath = (char*)Marshal::StringToHGlobalAnsi(path).ToPointer();
    int result = this->m_crane->LoadTrajFile(ppath);
    Marshal::FreeHGlobal((System::IntPtr)(void*)ppath);
    return result;
}

int WrapperDll::WrapperCrane::SetTrajBuffer( floatJaggedArray^ traj, long size )
{
    // Creer le tableau (sur la stacK) qui contiendra les pointeurs des 3 trajectoires.
    float* ptraj[3];

    // Traite chaque trajectoire du tableau Managed pour les transferer en type natifs.
    for(int i=0;i<3;i++)
    {
        float* tempTraj = new float[size];

        for(int j=0;j<size;j++)
        {
            tempTraj[j]=traj[i][j];
        }

        ptraj[i] = tempTraj;
    }
    return this->m_crane->SetTrajBuffer(ptraj,size);

    // A verifier si les tempTraj sont relacher en sortant de la methode puisque le conteneur de ceux-ci etait sur la stack.
}

int WrapperDll::WrapperCrane::GetTrajBuffer( [Out] floatJaggedArray^% traj, [Out] long% size )
{
    float **ptraj = new float*[3];
    long *psize = new long();

    int toReturnValue = this->m_crane->GetTrajBuffer(ptraj,psize);

    size = *psize;
    // Devrait t-ont supprimer le contenu de la ref traj et d'en associer une autre a place?
    traj = gcnew floatJaggedArray(3);			

    //// Traite chaque trajectoire du tableau natifs pour les transferer en Managed.
    for(int i=0;i<3;i++)
    {
        traj[i] = gcnew array<float>(size);

        for(int j=0;j<size;j++)
        {
            traj[i][j] = ptraj[i][j];
        }					
    }

    return toReturnValue;
}

int WrapperDll::WrapperCrane::SetTrajMode( int trajMode )
{
    return this->m_crane->SetTrajMode(trajMode);
}

int WrapperDll::WrapperCrane::GetTrajMode( void )
{
    return this->m_crane->GetTrajMode();
}

int WrapperDll::WrapperCrane::LoadCompFile( System::String^ path )
{
    char* ppath = (char*)Marshal::StringToHGlobalAnsi(path).ToPointer();
    int result = this->m_crane->LoadCompFile(ppath);
    Marshal::FreeHGlobal((System::IntPtr)(void*)ppath);
    return result;
}

int WrapperDll::WrapperCrane::SetComp( WrapperCompParamdef comp )
{
    return this->m_crane->SetComp(this->WrapperCompParamdefToCompParamdef(comp));
}

WrapperDll::WrapperCompParamdef WrapperDll::WrapperCrane::GetComp( void )
{
    return CompParamdefToWrapperCompParamdef(this->m_crane->GetComp());
}

int WrapperDll::WrapperCrane::OpenSensorFile( System::String^ path )
{
    char* ppath = (char*)Marshal::StringToHGlobalAnsi(path).ToPointer();
    int result = this->m_crane->OpenSensorFile(ppath);
    Marshal::FreeHGlobal((System::IntPtr)(void*)ppath);
    return result;
}

int WrapperDll::WrapperCrane::CloseSensorFile( void )
{
    return this->m_crane->CloseSensorFile();
}

int WrapperDll::WrapperCrane::GetSensor( [Out] System::Collections::Generic::List<float>^% sensorValue )
{
    float innerSensorValue[5];
    int returnValue = this->m_crane->GetSensor(innerSensorValue);

    for(int i=0;i<5;i++)
    {
        sensorValue->Add(innerSensorValue[i]);
    }

    return returnValue;
}

int WrapperDll::WrapperCrane::GetScale( [Out] System::Collections::Generic::List<float>^% scaleValue )
{
    float innerSensorValue[5];
    int returnValue = this->m_crane->GetScale(innerSensorValue);

    for(int i=0;i<5;i++)
    {
        scaleValue->Add(innerSensorValue[i]);
    }

    return returnValue;
}

int WrapperDll::WrapperCrane::SetScale( System::Collections::Generic::List<float>^ scaleValue )
{
    float innerSensorValue[5];
    for(int i=0;i<5;i++)
    {
        innerSensorValue[i] = scaleValue[i];
    }

    return this->m_crane->SetScale(innerSensorValue);
}
